package com.spic.business.train.plan.domain;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.google.common.collect.Lists;
import com.spic.business.train.plan.service.YearPlanService;
import com.spic.common.core.web.domain.AjaxResult;
import com.spic.common.security.utils.DictUtils;
import com.spic.common.security.utils.cache.DeptCacheUtils;
import com.spic.system.api.domain.SysDictData;
import com.spic.system.api.dto.DeptDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * YearPlanReadListener
 *
 * @author xuxiaochang@chinasofi.com
 * @date 2022/7/17
 */
public class YearPlanReadListener extends AnalysisEventListener<YearPlanExcel>
{
    Logger logger = LoggerFactory.getLogger(YearPlanReadListener.class);

    List<YearPlanExcel> list = Lists.newArrayList();

    List<CellExtra> extras = Lists.newArrayList();

    AjaxResult ajaxResult = null;

    private YearPlanService yearPlanService;

    private int count = 0;

    private Map<Integer, String> headMap = null;

    public YearPlanReadListener(AjaxResult result, YearPlanService yearPlanService)
    {
        this.ajaxResult = result;
        this.yearPlanService = yearPlanService;
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context)
    {
        super.invokeHead(headMap, context);
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context)
    {
        if (count == 0)
        {
            this.headMap = headMap;
        }
        count ++;
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception
    {
        super.onException(exception, context);
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context)
    {
        switch (extra.getType())
        {
            case MERGE:
                logger.error("extra:第{}行,第{}列,{},{},{},{}", extra.getRowIndex(),extra.getColumnIndex(), extra.getFirstRowIndex(), extra.getLastRowIndex(),extra.getFirstColumnIndex(), extra.getLastColumnIndex());
                extras.add(extra);
                break;
            default:

        }
    }

    @Override
    public boolean hasNext(AnalysisContext context)
    {
        return super.hasNext(context);
    }

    @Override
    public void invoke(YearPlanExcel data, AnalysisContext context)
    {
        list.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context)
    {
        String title = String.valueOf(LocalDate.now().plusYears(1).getYear());
        if (headMap != null)
        {
            String excelTitle = headMap.get(0) == null ? "" : headMap.get(0);
            String reg = "\\d{4}";
            Pattern p = Pattern.compile(reg);
            Matcher matcher = p.matcher(excelTitle);
            if (matcher.find())
            {
                title = matcher.group();
            }
        }
        //过滤出数据行中合并单元格的情况
        List<CellExtra> collect = extras.stream().filter(item -> item.getRowIndex() >= 4 && item.getColumnIndex() == 0).collect(Collectors.toList());
        //计算合并情况，并填充相关数据
        for (CellExtra cellExtra : collect)
        {
            Integer firstRowIndex = cellExtra.getFirstRowIndex();
            Integer lastRowIndex = cellExtra.getLastRowIndex();
            //被合并的数据
            YearPlanExcel first = list.get(firstRowIndex - 4);
            String trainType = first.getTrainType();
            //填充那些被合并的数据
            for (int i = firstRowIndex -4 +1; i <= lastRowIndex -4; i++)
            {
                YearPlanExcel current = list.get(i);
                current.setTrainType(trainType);
            }
        }
        //转换字典数据
        List<DeptDTO> deptDTOList = DeptCacheUtils.getCache();
        Map<String, Long> data = deptDTOList.stream().filter(item ->
                {
                    String ancestors = item.getAncestors();
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(ancestors))
                    {
                        return ancestors.split(",").length == 2;
                    }
                    else
                    {
                        return true;
                    }
                }
        ).collect(Collectors.toMap(DeptDTO::getDeptName, DeptDTO::getDeptId, (k1, k2) -> k2));
        List<SysDictData> methods = DictUtils.getDictCache("train_method");
        Map<String, String> methodMap = methods.stream().collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
        List<SysDictData> ways = DictUtils.getDictCache("choose_way");
        Map<String, String> waysMap = ways.stream().collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
        List<SysDictData> asses = DictUtils.getDictCache("assessment_method");
        Map<String, String> assesMap = asses.stream().collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
        //保存数据
        for (YearPlanExcel yearPlanExcel : list)
        {
            yearPlanExcel.setYear(title);
            yearPlanExcel.setTrainMethod(methodMap.get(yearPlanExcel.getTrainMethod()));
            yearPlanExcel.setAssessmentMethod(assesMap.get(yearPlanExcel.getAssessmentMethod()));
            yearPlanExcel.setChooseWay(waysMap.get(yearPlanExcel.getChooseWay()));
            yearPlanExcel.setTrainDept(data.get(yearPlanExcel.getDeptName()));
        }
        yearPlanService.saveBatch(list);
    }
}
